package cn.caskm.souvenirshopsystem.service.impl;

import cn.caskm.souvenirshopsystem.constants.BizConstants;
import cn.caskm.souvenirshopsystem.domain.Result;
import cn.caskm.souvenirshopsystem.domain.dto.PageDTO;
import cn.caskm.souvenirshopsystem.domain.po.Goods;
import cn.caskm.souvenirshopsystem.domain.po.ShoppingCart;
import cn.caskm.souvenirshopsystem.domain.query.PageQuery;
import cn.caskm.souvenirshopsystem.domain.vo.ShopCartVO;
import cn.caskm.souvenirshopsystem.exceptions.BizException;
import cn.caskm.souvenirshopsystem.mapper.GoodsMapper;
import cn.caskm.souvenirshopsystem.mapper.ShoppingCartMapper;
import cn.caskm.souvenirshopsystem.service.ShoppingCartService;
import cn.caskm.souvenirshopsystem.utils.UserContext;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class ShoppingCartServiceImpl extends ServiceImpl<ShoppingCartMapper, ShoppingCart> implements ShoppingCartService {

    private final GoodsMapper goodsMapper;

    @Override
    public Result<PageDTO<ShoppingCart>> page(PageQuery query) {
        // 获取参数
        Long pageNum = query.getPageNum();
        if (pageNum == null) {
            pageNum = BizConstants.DEFAULT_PAGE_NUM;
        }
        Long pageSize = query.getPageSize();
        if (pageSize == null) {
            pageSize = BizConstants.DEFAULT_PAGE_SIZE;
        }

        // 查询数据
        Page<ShoppingCart> page = lambdaQuery()
                .orderByDesc(ShoppingCart::getCreateTime)
                .page(new Page<>(pageNum, pageSize));
        
        List<ShoppingCart> records = page.getRecords();
        return Result.success(PageDTO.of(records, page.getPages(), page.getTotal()));
    }
    
    @Override
    public Result<List<ShoppingCart>> getAll() {
        List<ShoppingCart> list = lambdaQuery()
                .orderByDesc(ShoppingCart::getCreateTime)
                .list();
        return Result.success(list);
    }

    @Override
    public Result<ShoppingCart> detail(Integer id) {
        ShoppingCart shoppingCart = getById(id);
        if (shoppingCart == null) {
            throw new BizException("购物车信息不存在");
        }
        return Result.success(shoppingCart);
    }

    @Override
    public void saveOrUpdateEntity(ShoppingCart shoppingCart) {
        if (shoppingCart.getCartId() == null) {
            // 新增购物车
            shoppingCart.setCreateTime(LocalDateTime.now());
            save(shoppingCart);
        } else {
            // 修改购物车
            updateById(shoppingCart);
        }
    }

    @Override
    public void addOrRemoveGoodsToCart(Integer goodsId, Boolean ifAdd) {
        // 查询购物车信息
        int userId = UserContext.getUser().intValue();
        ShoppingCart cart = lambdaQuery()
                .eq(ShoppingCart::getGoodsId, goodsId)
                .eq(ShoppingCart::getUserId, userId)
                .one();

        // 查询商品信息
        Goods goods = goodsMapper.selectById(goodsId);

        // 设置购物车信息
        if (cart == null) {
            if (BooleanUtil.isFalse(ifAdd)) {
                throw new BizException("异常，你的购物车没有该商品信息并尝试减少数量！！！");
            }
            cart = new ShoppingCart();
            cart.setGoodsId(goodsId);
            cart.setUserId(userId);
            cart.setFlag(1);
            cart.setPrice(goods.getGoodsPrice());
            cart.setCreateTime(LocalDateTime.now());
            cart.setGoodsNum(1);
            save(cart);
        } else {
            // 根据情况加1或者减1
            if (BooleanUtil.isTrue(ifAdd)) {
                cart.setPrice(cart.getPrice().add(goods.getGoodsPrice()));
                cart.setGoodsNum(cart.getGoodsNum() + 1);
            } else {
                cart.setPrice(cart.getPrice().subtract(goods.getGoodsPrice()));
                cart.setGoodsNum(cart.getGoodsNum() - 1);
            }
            updateById(cart);
        }

    }

    @Override
    public void updateAllCheckStatus(Boolean flag) {
        // 查询用户所有的购物车信息
        Long userId = UserContext.getUser();
        List<ShoppingCart> list = lambdaQuery()
                .eq(ShoppingCart::getUserId, userId.intValue())
                .list();

        // 设置选中状态
        list.forEach(item -> item.setFlag(BooleanUtil.isTrue(flag) ? 1 : 0));

        // 更新
        updateBatchById(list);
    }

    @Override
    public void deleteCart(List<Integer> goodsIds) {
        // 获取登录用户
        Long userId = UserContext.getUser();

        // 删除购物车信息
        LambdaQueryWrapper<ShoppingCart> wrapper = Wrappers.lambdaQuery(ShoppingCart.class)
                .eq(ShoppingCart::getUserId, userId.intValue())
                .in(ShoppingCart::getGoodsId, goodsIds);
        remove(wrapper);
    }

    @Override
    public Result<List<ShopCartVO>> listCart() {
        // 获取登录用户
        Long userId = UserContext.getUser();

        // 获取购物车信息
        List<ShoppingCart> listCart = lambdaQuery()
                .eq(ShoppingCart::getUserId, userId.intValue())
                .list();
        if (CollUtil.isEmpty(listCart)) {
            return Result.success(Collections.emptyList());
        }

        // 获取商品信息
        Set<Integer> goodsIds = listCart.stream().map(ShoppingCart::getGoodsId).collect(Collectors.toSet());
        List<Goods> listGoods = goodsMapper.selectBatchIds(goodsIds);
        if (CollUtil.isEmpty(listGoods)) {
            throw new BizException("商品信息为空");
        }
        Map<Integer, Goods> goodsMap = listGoods.stream().collect(Collectors.toMap(Goods::getGoodsId, g -> g));

        // 组装VO
        List<ShopCartVO> result = new ArrayList<>(listCart.size());
        for (ShoppingCart cart : listCart) {
            Integer goodsId = cart.getGoodsId();
            Goods goods = goodsMap.get(goodsId);
            if (goods == null) {
                continue;
            }
            ShopCartVO vo = new ShopCartVO();
            vo.setCartId(cart.getCartId());
            vo.setPrice(cart.getPrice());
            vo.setGoodsNum(cart.getGoodsNum());
            vo.setGoodsName(goods.getGoodsName());
            vo.setPicture(goods.getImage());
            vo.setDesc(goods.getGoodsDesc());
            vo.setGoodsId(goodsId);
            result.add(vo);
        }

        return Result.success(result);
    }
}
